1 : <?php
2 : /*--------------------------------------------------------------------------+
3 : This file is part of eStudy.
4 : common/classes/class.passwords.inc.php
5 : - Modulgruppe: Framework
6 : - Beschreibung: Klasse zum Erzeugen und Prüfen von Passwörtern
7 : - Version: $Id: class.passwords.inc.php,v 1.4.20.4 2008/01/07 14:36:21 commana Exp $
8 : - Autor(en): Rolf Viehmann (hg12057) <rolfhub@web.de>
9 : Jörg Rieger <joerg.rieger@mni.fh-giessen.de>
10 : Markus Keim <markus.keim@mni.fh-giessen.de>
11 : Vitaliy Shkarupa <vitaliy_shkarupa@web.de>
12 : +---------------------------------------------------------------------------+
13 : This program is free software; you can redistribute it and/or
14 : modify it under the terms of the GNU General Public License
15 : as published by the Free Software Foundation; either version 2
16 : of the License, or any later version.
17 : +---------------------------------------------------------------------------+
18 : This program is distributed in the hope that it will be useful,
19 : but WITHOUT ANY WARRANTY; without even the implied warranty of
20 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 : GNU General Public License for more details.
22 : You should have received a copy of the GNU General Public License
23 : along with this program; if not, write to the Free Software
24 : Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 : +--------------------------------------------------------------------------*/
26 : define("PASSWORD_OK", 0);
27 : define("PASSWORD_TOO_SHORT", 1);
28 : define("PASSWORD_TOO_LONG", 2);
29 : define("PASSWORD_IN_WORDLIST", 3);
30 : define("PASSWORD_NO_SPECIAL_CHAR", 4);
31 : define("PASSWORD_NO_DIGIT", 5);
32 : define("PASSWORD_ONLY_ONE_CASE_CHARS", 6);
33 : define("PASSWORD_NO_DIGIT_OR_SPECIAL_CHAR", 7);
34 : define("PASSWORD_GENERATED_FROM_USER_INPUT", 8);
35 : define("HASH_XPWEB", 1);
36 : define("HASH_MEDIAWIKI", 2);
37 : define("HASH_MANTIS", 3);
38 : define("MIN_LENGTH_DEFAULT", 8);
39 : define("MAX_LENGTH_DEFAULT", 32);
40 : define("DIGIT_AND_CHARS_DEFAULT", 0);
41 : require_once (PATH_TO_ROOT."common/classes/class.data.inc.php");
42 : /**
43 : * Klasse zum Erzeugen und Prüfen von Passwörtern
44 : * @package Framework
45 : * @version $Id: class.passwords.inc.php,v 1.4.20.4 2008/01/07 14:36:21 commana Exp $
46 : * @author Rolf Viehmann (hg12057) <rolfhub@web.de>
47 : * @author Vitaliy Shkarupa <vitaliy_shkarupa@web.de>
48 : * @author Simon Thum (hg9515)
49 : * @author Markus Keim <markus.keim@mni.fh-giessen.de>
50 : */
51 : class Passwords {
52 : /**
53 : * Wrapper für checkPasswordAdvanced(), gibt einfach nur true oder false zurück.
54 : * Alle Parameter wie bei checkPasswordAdvanced().
55 : * @return bool - Passwort akzeptabel (true) oder nicht (false)
56 : */
57 : public static function checkPassword($password, $qualityCheck = true) {
58 0 : $tmp = Passwords::checkPasswordAdvanced($password, $qualityCheck);
59 0 : return ($tmp === PASSWORD_OK);
60 : }
61 : /**
62 : * Prüft, ob ein Passwort (im Bezug auf die Länge) die Kriterien erfüllt.
63 : * Optional kann man prüfen lassen, ob das Passwort nur erlaubte Zeichen enthält.
64 : * Später werden weitere Prüfungen hinzukommen.
65 : *
66 : * @param string $password - Das Passwort
67 : * @param int $minlen - Mindestlänge in Zeichen
68 : * @param int $maxlen - Maximallänge in Zeichen
69 : * @return eine der Konstanten (PASSWORD_*) ODER Array aus diesen
70 : */
71 : public static function checkPasswordAdvanced($password, $qualityCheck = true) {
72 0 : $password = Data::gpcUnescape($password);
73 0 : $errorCount = 0;
74 :
75 0 : if (Passwords::testMinLength($password) == false) $result[$errorCount++] = PASSWORD_TOO_SHORT; // Passwort zu kurz
76 0 : if (Passwords::testMaxLength($password) == false) $result[$errorCount++] = PASSWORD_TOO_LONG; // Passwort zu lang
77 0 : if ($qualityCheck == false) return ($errorCount == 0) ? PASSWORD_OK : $result;
78 0 : if (Passwords::testCaseChars($password) == false) $result[$errorCount++] = PASSWORD_ONLY_ONE_CASE_CHARS; // Passwort enthält Zeichen nur in einem Register
79 0 : if (Passwords::testWordlist($password) == false) $result[$errorCount++] = PASSWORD_IN_WORDLIST; // Passwort ist in der Wortliste zu finden
80 0 : if (Passwords::isDigitsAndSpecialChars()) {
81 0 : if (Passwords::testDigit($password) == false) $result[$errorCount++] = PASSWORD_NO_DIGIT; // Passwort enthält keine Zahlen
82 0 : if (Passwords::testSpecialChars($password) == false) $result[$errorCount++] = PASSWORD_NO_SPECIAL_CHAR; // Passwort enthält keine Sonderzeichen
83 :
84 0 : } else {
85 0 : if ((Passwords::testDigit($password) == false) AND (Passwords::testSpecialChars($password) == false)) $result[$errorCount++] = PASSWORD_NO_DIGIT_OR_SPECIAL_CHAR; // Passwort enthält keine Sonderzeichen und keine Zahlen
86 :
87 : }
88 0 : return ($errorCount == 0) ? PASSWORD_OK : $result;
89 : }
90 : private static function genPwHelper($class) {
91 0 : $rnd = mt_rand(0, count($class) -1);
92 0 : return $class[$rnd];
93 : }
94 : /**
95 : * Generiert ein Zufallspasswort (mit der entsprechenden Länge)
96 : *
97 : * @param int $len - Die gewünschte Länge (in Zeichen)
98 : * Falls Länge=0: Der systemweit festgelegte Defaultwert wird verwendet
99 : * @return string - Zufallspasswort
100 : */
101 : public static function generateRandomPassword($len = 0) {
102 0 : $trick = 0;
103 0 : $pw = "";
104 0 : if ($len == 0) $len = Passwords::getPasswordMaxLength(); // oder: getPasswordMinLength()
105 0 : while (strlen($pw) < $len) {
106 : switch ($trick) {
107 0 : case 0:
108 0 : $pw = $pw.strtoupper(Passwords::genPwHelper(Passwords::getLetters()));
109 0 : case 1:
110 0 : $pw = $pw.Passwords::genPwHelper(Passwords::getLetters());
111 0 : case 2:
112 0 : $pw = $pw.Passwords::genPwHelper(Passwords::getNumbers());
113 0 : case 3:
114 0 : $pw = $pw.Passwords::genPwHelper(Passwords::getSpecialChars());
115 0 : }
116 0 : $trick = mt_rand(0, 3);
117 0 : }
118 0 : return substr($pw, 0, $len);
119 : }
120 : /**
121 : * Generiert einen Hash zu einem Passwort (derzeit per Default per MD5).
122 : * Der Salt ist optional (außer bei custom_mediawiki, da ist es die userid).
123 : *
124 : * @param string $password - Das zu hashende Passwort (vom User eingegeben)
125 : * @param string $salt - Der zum Hashen des Passwortes zu benutzende Salt (z. B. der Username)
126 : * @param string $algo - Der zu verwendende Algorithmus
127 : * Mögliche Werte: Eine der Konstanten (Hash_*) oder
128 : * ein Eintrag aus der Liste, die die Funktion hash_algos() ausgibt.
129 : * @return string - Hash
130 : */
131 : public static function generateHash($password, $salt = '', $algo = 'MD5') {
132 0 : $password = Data::gpcUnescape($password);
133 :
134 : // XPWeb verwendet derzeit einfach MD5 'pur' (könnte sich aber in Zukunft ändern)
135 0 : if ($algo === HASH_XPWEB) {
136 0 : return md5($salt.$password);
137 : }
138 : // Mediawiki hat einen eigenen Algorithmus
139 0 : if ($algo === HASH_MEDIAWIKI) {
140 0 : if ($salt == '') return false;
141 0 : $p = md5($password);
142 0 : return md5("{$salt}-{$p}");
143 : }
144 : // Mantis verwendet derzeit einfach MD5 'pur' (könnte sich aber in Zukunft ändern)
145 0 : if ($algo === HASH_MANTIS) {
146 0 : return md5($salt.$password);
147 : }
148 : // allgemeine Hash-Funktion
149 0 : $algo = strtolower($algo);
150 0 : $tmp = $salt.$password;
151 0 : return hash($algo, $tmp);
152 : }
153 : /**
154 : * Generiert einen zufälligen Passwort-Hash
155 : *
156 : * @return string - Hash
157 : */
158 : public static function generateRandomHash() {
159 0 : return Passwords::generateHash(Passwords::generateRandomPassword(50));
160 : }
161 : /**
162 : * Generiert ein neues Passwort basierend auf der Nutzer Eingabe
163 : *
164 : * @param string $password - Das zu vom Nutzer eingegebene Passwort
165 : * @param array $errorResult - Das Fehler Array
166 : * @return string
167 : */
168 : public static function generatePasswordFromUserInput($password, $errorResult) {
169 0 : $newPassword = Data::gpcUnescape($password);
170 :
171 0 : foreach($errorResult as $key => $val) {
172 : switch ($val) {
173 0 : case PASSWORD_TOO_SHORT:
174 0 : $newPassword = Passwords::makeMinLength($newPassword);
175 0 : break;
176 :
177 0 : case PASSWORD_NO_DIGIT:
178 0 : $newPassword = Passwords::makeDigit($newPassword);
179 0 : break;
180 :
181 0 : case PASSWORD_NO_SPECIAL_CHAR:
182 0 : $newPassword = Passwords::makeSpecialChars($newPassword);
183 0 : break;
184 :
185 0 : case PASSWORD_ONLY_ONE_CASE_CHARS:
186 0 : $newPassword = Passwords::makeCaseChars($newPassword);
187 0 : break;
188 :
189 0 : case PASSWORD_NO_DIGIT_OR_SPECIAL_CHAR:
190 0 : $newPassword = Passwords::makeDigit($newPassword);
191 0 : $newPassword = Passwords::makeSpecialChars($newPassword);
192 0 : break;
193 :
194 0 : case PASSWORD_IN_WORDLIST:
195 0 : $newPassword = Passwords::makeCaseChars($newPassword);
196 0 : $newPassword = Passwords::makeDigit($newPassword);
197 0 : $newPassword = Passwords::makeSpecialChars($newPassword);
198 0 : break;
199 :
200 0 : case PASSWORD_TOO_LONG:
201 0 : $newPassword = Passwords::makeMaxLength($newPassword);
202 0 : break;
203 : }
204 0 : }
205 0 : $errorResult = Passwords::checkPasswordAdvanced($newPassword, true);
206 0 : if ($errorResult == 0) return $newPassword;
207 0 : else return Passwords::generatePasswordFromUserInput($newPassword, $errorResult);
208 : }
209 : /**
210 : * Prüft, ob ein eingegebenes Passwort korrekt ist, wobei der (z. B. in der
211 : * DB gespeicherte) Hash des Passwortes nötig ist, außerdem wird der Salt
212 : * benötigt, der verwendet wurde, um den Hash zu erzeugen.
213 : *
214 : * @param string $password - Das zu testende Passwort (vom User eingegeben)
215 : * @param string $hash - Der hinterlegte Hash
216 : * @param string $salt - Der zum Hashen des Passwortes benutzte Hash
217 : * @return bool - Passwort korrekt oder nicht
218 : */
219 : public static function verifyPassword($password, $hash, $salt = '', $algo = 'MD5') {
220 0 : $tmp = Passwords::generateHash($password, $salt, $algo);
221 0 : return ($tmp === $hash);
222 : }
223 : /**
224 : * Gibt eine Fehlermeldung zu einem Fehlercode (Konstanten (Password*)) zurück
225 : * @param int ODER array - Der Fehlercode (oder Array von Codes)
226 : * @return string - Die Fehlermeldung
227 : */
228 : public static function errorConstToString($errorResult) {
229 0 : $errorStrings = array(PASSWORD_OK => "Das Passwort ist OK.", PASSWORD_TOO_SHORT => "Das Passwort ist kürzer als die geforderte Mindestlänge von <strong>".Passwords::getPasswordMinLength() ."</strong> Zeichen.", PASSWORD_TOO_LONG => "Das Passwort überschreitet die zugelassene Maximallänge von <strong>".Passwords::getPasswordMaxLength() ."</strong> Zeichen.", PASSWORD_IN_WORDLIST => "Das Passwort ist in der Wortliste zu finden und somit leicht zu erraten.", PASSWORD_NO_SPECIAL_CHAR => "Das Passwort enthält keine Sonderzeichen.", PASSWORD_NO_DIGIT => "Das Passwort enthält keine Zahlen.", PASSWORD_ONLY_ONE_CASE_CHARS => "Das Passwort enthält keine Groß- <strong>und</strong> Kleinbuchstaben.", PASSWORD_NO_DIGIT_OR_SPECIAL_CHAR => "Das Passwort muss entweder Zahlen oder Sonderzeichen enthalten.", PASSWORD_GENERATED_FROM_USER_INPUT => "So könnte ein gültiges Passwort anhand Ihrer Eingabe aussehen: ");
230 0 : if (!is_array($errorResult)) return $errorStrings[$errorResult];
231 0 : $resultString = "";
232 0 : $separator = "<br />";
233 0 : foreach($errorResult as $value) $resultString.= $errorStrings[$value].$separator;
234 0 : return $resultString;
235 : }
236 : /**
237 : * Gibt die minimale Länge für Passwörter zurück, wobei die Systemeinstellung berücksichtigt wird.
238 : * @return int
239 : */
240 : public static function getPasswordMinLength() {
241 0 : global $settings;
242 0 : if (is_numeric($settings['register_min_pass_length'])) return $settings['register_min_pass_length'];
243 0 : return MIN_LENGTH_DEFAULT;
244 : }
245 : /**
246 : * Gibt die maximale Länge für Passwörter zurück
247 : * @return int
248 : */
249 : public static function getPasswordMaxLength() {
250 0 : global $settings;
251 0 : if (is_numeric($settings['register_max_pass_length'])) return $settings['register_max_pass_length'];
252 0 : return MAX_LENGTH_DEFAULT;
253 : }
254 : /**
255 : * Gibt eine Eigenschaft (entweder "Zahlen UND Sonderzeichen", oder "Zahlen ODER Sonderzeichen")
256 : * @return bool (TRUE beim "UND", FALSE beim "ODER")
257 : */
258 : public static function isDigitsAndSpecialChars() {
259 0 : global $settings;
260 0 : if (is_bool($settings['register_pass_digits_und_special_chars'])) $result = $settings['register_pass_digits_und_special_chars'];
261 0 : else $result = DIGIT_AND_CHARS_DEFAULT;
262 0 : return ($result == 1) ? true : false;
263 : }
264 : /**
265 : * Prüft, ob der Länge des Passwortes der minimalen Länge entspricht
266 : *
267 : * @param string $password - Das zu testende Passwort
268 : * @return boolean
269 : */
270 : public static function testMinLength($password) {
271 0 : $minLength = Passwords::getPasswordMinLength();
272 0 : return (strlen($password) < $minLength) ? false : true;
273 : }
274 : /**
275 : * Erweitert ein Passwort auf die Mindestlänge
276 : *
277 : * @param string $password - Das zu testende Passwort
278 : * @return string
279 : */
280 : public static function makeMinLength($password) {
281 0 : if (strlen($password) >= Passwords::getPasswordMinLength()) return false;
282 0 : $fill = Passwords::getPasswordMinLength() -strlen($password) -2;
283 0 : $specialChars = Passwords::getSpecialChars();
284 0 : $letters = Passwords::getLetters();
285 0 : mt_srand((double)microtime() *1000000);
286 0 : $random = mt_rand();
287 0 : shuffle($specialChars);
288 0 : shuffle($letters);
289 0 : return $specialChars[0].$password.substr($random, 0, $fill) .$specialChars[1].strtoupper($letters[1]);
290 : }
291 : /**
292 : * Prüft, ob der Länge des Passwortes der maximalen Länge entspricht
293 : * @return boolean
294 : */
295 : public static function testMaxLength($password) {
296 0 : $maxLength = Passwords::getPasswordMaxLength();
297 0 : return (strlen($password) > $maxLength) ? false : true;
298 : }
299 : /**
300 : * Reduziert ein Passwort auf die Maximallänge
301 : *
302 : * @param string $password - Das zu testende Passwort
303 : * @return string
304 : */
305 : public static function makeMaxLength($password) {
306 0 : return substr($password, 0, Passwords::getPasswordMaxLength());
307 : }
308 : /**
309 : * Prüft, ob das Passwort Zeichen in verschiedenen Registern enthält
310 : * @return boolean
311 : */
312 : public static function testCaseChars($password) {
313 0 : if (ereg("[A-Z]", $password) and ereg("[a-z]", $password)) return true;
314 0 : else return false;
315 : }
316 : /**
317 : * Fügt Zeichen aus verschiedenen Registern ein
318 : *
319 : * @param string $password - Das zu testende Passwort
320 : * @return string
321 : */
322 : public static function makeCaseChars($password) {
323 0 : $fill = Passwords::getPasswordMaxLength() -strlen($password);
324 0 : $letters = Passwords::getLetters();
325 0 : mt_srand((double)microtime() *1000000);
326 0 : $random = mt_rand();
327 0 : shuffle($letters);
328 0 : if ($fill > 1) return strtoupper($letters[0]) .$password.$letters[1];
329 0 : else return strtoupper($letters[0]) .substr($password, 0, Passwords::getPasswordMaxLength() -2) .strtoupper($letters[1]);
330 : }
331 : /**
332 : * Prüft, ob das Passwort Sonderzeichen enthält
333 : * @param string $password
334 : * @return boolean
335 : */
336 : public static function testSpecialChars($password) {
337 0 : if (ereg("[^0-9A-Za-z]", $password)) return true;
338 0 : else return false;
339 : }
340 : /**
341 : * Fügt Sonderzeichen ein
342 : *
343 : * @param string $password - Das zu testende Passwort
344 : * @return string
345 : */
346 : public static function makeSpecialChars($password) {
347 0 : $fill = Passwords::getPasswordMaxLength() -strlen($password);
348 0 : $specialChars = Passwords::getSpecialChars();
349 0 : mt_srand((double)microtime() *1000000);
350 0 : $random = mt_rand();
351 0 : shuffle($specialChars);
352 0 : if ($fill > 1) return $specialChars[0].$password.$specialChars[1];
353 0 : else return $specialChars[0].substr($password, 0, Passwords::getPasswordMaxLength() -2) .$specialChars[1];
354 : }
355 : /**
356 : * Prüft, ob eine Wortliste das Passwort enthält (TRUE wenn das Passwort nicht gefunden ist => ein Test ist bestanden)
357 : * @return boolean
358 : */
359 : public static function testWordlist($password) {
360 0 : global $db;
361 : /*
362 : * Beim setup kann noch keine DB-Verbindung existieren (DB-login/-password/-name usw. fehlen),
363 : * daher ist eine Abfrage der Wordlist nicht möglich
364 : */
365 0 : if (!$db) return true;
366 0 : $result = $db->get_var("SELECT word FROM password_wordlist WHERE word='".Data::toMysql($password) ."' OR word='".Data::toMysql(strrev($password)) ."'");
367 0 : if (is_string($result)) return false;
368 0 : else return true;
369 : }
370 : /**
371 : * Prüft, ob das Passwort Zahlen enthält
372 : * @return boolean
373 : */
374 : public static function testDigit($password) {
375 0 : if (ereg("[0-9]", $password)) return true;
376 0 : else return false;
377 : }
378 : /**
379 : * Fügt Zahlen am Anfang ein
380 : *
381 : * @param string $password - Das zu testende Passwort
382 : * @return string
383 : */
384 : public static function makeDigit($password) {
385 0 : $fill = Passwords::getPasswordMaxLength() -strlen($password);
386 0 : mt_srand((double)microtime() *1000000);
387 0 : $random = mt_rand();
388 0 : if ($fill > 1) return substr($random, 0, 2) .$password;
389 0 : else return substr($random, 0, 2) .substr($password, 0, Passwords::getPasswordMaxLength() -2);
390 : }
391 : /**
392 : * Sendet eine private Nachricht um den Nutzer auf sein schwaches Passwort aufmerksam zu machen
393 : *
394 : * @param string - User-Login
395 : * @param bool $ldapUser - Ldap User
396 : * @param int ODER array - Der Fehlercode (oder Array von Codes)
397 : * @return true
398 : */
399 : public static function sendMessageByLoginWithPasswordProblems($login, $ldapUser, $errorResult) {
400 0 : global $db, $settings;
401 0 : require_once (PATH_TO_ROOT."messaging/classes/class.messaging.inc.php");
402 : // Keine Message an den Anonym-Benutzer versenden
403 0 : if (strtolower($login) == 'anonymus' || strtolower($login) == 'anonymer' || strtolower($login) == 'anonym') return false;
404 0 : $userData = $db->get_row("SELECT Vorname, Nachname, ID, gender, salutation, num_weak_pwd_msg FROM user WHERE Login = '".Data::toMysql($login) ."'");
405 :
406 0 : if ((int)$settings["max_num_weak_pwd_msg"] > 0) {
407 : /* Zähler für Benachrichtigungen inkrementieren */
408 0 : $numWeakPwdMsg = (int)$userData->num_weak_pwd_msg + 1;
409 0 : $db->query("UPDATE user SET num_weak_pwd_msg = '$numWeakPwdMsg' WHERE ID = '" . $userData->ID . "'");
410 0 : }
411 :
412 : // Anrede inkl. Titel (sofern vorhanden)
413 0 : $salutation = Passwords::getSalutation($userData);
414 :
415 0 : $recipient = $userData->Nachname.", ".$userData->Vorname;
416 0 : $subject = "Ihr Passwort entspricht nicht den eStudy-Richtlinien!";
417 : // HTML-Tags durch BBCode-Tags ersetzen
418 0 : $errors = str_replace('<br />', "\n", Passwords::errorConstToString($errorResult));
419 0 : $errors = str_replace('<strong>', "[b]", $errors);
420 0 : $errors = str_replace('</strong>', "[/b]", $errors);
421 : // Wenn der Nutzer ein LDAP-Benutzer ist, bekommt er eine spezielle URL zur Passwortänderung
422 0 : if ($ldapUser && isset($settings['ldap_change_password_url']) && $settings['ldap_change_password_url'] != '') $url = "\n[url=".$settings['ldap_change_password_url']."]Passwort ändern (LDAP Benutzer)[/url]";
423 0 : else $url = "\n[url=http://".$_SERVER['SERVER_NAME'].substr($_SERVER['PHP_SELF'], 0, strrpos($_SERVER['PHP_SELF'], '/')) ."/user/changepassword.php?user=".$userData->ID."]Passwort ändern[/url]";
424 0 : $text = $salutation . ",\n\neStudy hat folgende Probleme mit Ihrem Passwort festgestellt:\n\n" .
425 0 : $errors . "\n" . Passwords::getUserHint() .
426 0 : "\n\nDieser Hinweis wird insgesamt " . $settings["max_num_weak_pwd_msg"] . " Mal angezeigt, um Ihnen die Möglichkeit zu geben, Ihr Passwort anzupassen. Danach erfolgt eine Sperrung Ihres Accounts, die nur vom eStudy-Adminstrator aufgehoben werden kann. Dies ist der $numWeakPwdMsg. Hinweis.\n" . $url;
427 0 : $message = new Messaging(1); // Absender ist Admin (ID = 1)
428 0 : $message->sendMessage($recipient, $subject, $text, false, false);
429 :
430 0 : return true;
431 : }
432 :
433 : /**
434 : * Zeichen die als "Special Chars" benutzt werden können
435 : *
436 : * @return array
437 : */
438 : public static function getSpecialChars() {
439 0 : return array('ö', 'Ö', 'ä', 'Ä', 'ü', 'Ü', 'ß', ',', ';', '.', ':', '-', '_', '#', '\'', '+', '*', '!', '"', '§', '$', '%', '&', '/', '(', ')', '=', '?');
440 : }
441 : /**
442 : * Zahlen von 0-9
443 : *
444 : * @return array
445 : */
446 : public static function getNumbers() {
447 0 : return array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9');
448 : }
449 : /**
450 : * Buchstaben von a-z
451 : *
452 : * @return array
453 : */
454 : public static function getLetters() {
455 0 : return array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z');
456 : }
457 : /**
458 : * gibt einen Beschreibungsstring aus, der die eingestellten Passwortkriterien wiederspiegelt.
459 : */
460 : public static function getUserHint() {
461 0 : return "Das Passwort sollte zwischen ".Passwords::getPasswordMinLength() ." und ".Passwords::getPasswordMaxLength() ." Zeichen lang sein. "."Außerdem müssen Klein- und Großbuchstaben".(Passwords::isDigitsAndSpecialChars() ? ", Zahlen und Sonderzeichen " : " sowie Zahlen oder Sonderzeichen ") ."enthalten sein.";
462 : }
463 : /**
464 : * gibt einen Beschreibungsstring in HTML aus, der die eingestellten Passwortkriterien wiederspiegelt.
465 : */
466 : public static function getUserHintAsHTML() {
467 0 : return Data::toHTML(Passwords::getUserHint(), false);
468 : }
469 :
470 : /**
471 : * Gibt die Anrede zurück (Frau/Herr)
472 : *
473 : * @access public
474 : * @param $userData array
475 : * @return bool mixed
476 : */
477 : function getSalutation($userData) {
478 0 : if(!isset($userData->gender))
479 0 : return false;
480 :
481 0 : $salutation = '';
482 :
483 : // 0 = nicht definiert, 1 = Männlich, 2 = Weiblich
484 0 : switch($userData->gender) {
485 0 : case 0:
486 0 : $salutation = 'Hallo' . Passwords::getTitle($userData) . ' ' . Data::toHTML(ucfirst($userData->Vorname)) . ' ' . Data::toHTML(ucfirst($userData->Nachname));
487 0 : break;
488 0 : case 1:
489 0 : $salutation = 'Sehr geehrter Herr' . Passwords::getTitle($userData) . ' ' . Data::toHTML(ucfirst($userData->Nachname));
490 0 : break;
491 0 : case 2:
492 0 : $salutation = 'Sehr geehrte Frau' . Passwords::getTitle($userData) . ' ' . Data::toHTML(ucfirst($userData->Nachname));
493 0 : break;
494 0 : }
495 :
496 0 : return $salutation;
497 : }
498 :
499 : /**
500 : * Gibt den Akademischen Grad/Titel zurück zurück (Dr./Prof./Prof. Dr.)
501 : *
502 : * @access public
503 : * @param $userData array
504 : * @return bool mixed
505 : */
506 : function getTitle($userData) {
507 0 : if(!isset($userData->salutation))
508 0 : return false;
509 :
510 0 : $title = '';
511 :
512 : // 0 = nicht definiert, 1 = Herr, 2 = Frau, 3 = Dr., 4 = Prof., 5 = Prof. Dr., 6 = Prof. Dr. Dr.
513 0 : if(isset($userData->salutation)) {
514 0 : switch($userData->salutation) {
515 0 : case 3:
516 0 : $title = ' Dr.';
517 0 : break;
518 0 : case 4:
519 0 : $title = ' Prof.';
520 0 : break;
521 0 : case 5:
522 0 : $title = ' Prof. Dr.';
523 0 : break;
524 0 : case 6:
525 0 : $title = ' Prof. Dr. Dr.';
526 0 : break;
527 0 : }
528 0 : }
529 :
530 0 : return $title;
531 : }
532 :
533 : /**
534 : * Setzt eine Sperre, falls die in den Settings hinterlegte maximale Anzahl
535 : * von Benutzerbenachrichtigungen für ein nicht den eStudy-Richtlinien
536 : * entsprechendes Passwort erreicht wurde wurde.
537 : * @access public
538 : * @param int $userId die ID des aktuellen Users im Login-Prozess
539 : * @return mixed Die "UserBanning"-Instanz, falls Sperre gesetzt.
540 : * false, falls keine Sperre gesetzt wurde.
541 : */
542 : function setUserBanForIgnoredWeakPwdMsg($userId) {
543 0 : global $db, $settings;
544 : /* Benutzersperre abfragen */
545 0 : $ban = new UserBanning($userId);
546 0 : if ($ban->getBanID()) {
547 : /* User bereits gesperrt, wir geben die Instanz der Benutzersperre zurück */
548 0 : return $ban;
549 : }
550 : /* Maximal zulässige Anzahl der Benachrichtigungen auslesen */
551 0 : $maxNumWeakPwdMsg = (int)$settings["max_num_weak_pwd_msg"];
552 0 : if ($maxNumWeakPwdMsg <= 0) {
553 : /* Sperrmechanismus deaktiviert */
554 0 : return false;
555 : }
556 :
557 : /* Zähler für Benachrichtigungen auslesen */
558 0 : $numWeakPwdMsg = (int)$db->get_var("SELECT num_weak_pwd_msg FROM user WHERE ID = '". $userId ."'");
559 :
560 0 : if ($numWeakPwdMsg >= $maxNumWeakPwdMsg) {
561 : /* Benutzer sperren, wir verwenden die aktuelle Zeit, d.h. unbegrenzte Sperre */
562 0 : $lockTime = getdate(time());
563 0 : $hour = $lockTime["hours"];
564 0 : $minute = $lockTime["minutes"];
565 0 : $mon = $lockTime["mon"];
566 0 : $mday = $lockTime["mday"];
567 0 : $year = $lockTime["year"];
568 0 : $lockMsg = "Sie haben trotz wiederholter Sicherheitswarnungen vom Administrator der Lernplattform eStudy Ihr Passwort nicht den geltenden Richtlinien angepasst. Eine Aufhebung der Zugangssperre kann nur durch den Administrator erfolgen. Mailadresse: " . $settings["admin_email"] . ".";
569 0 : if ($ban->banUser(1, $lockMsg , $hour, $minute, $mon, $mday, $year)) {
570 : /* Zähler für Benachrichtigungen zurücksetzen */
571 0 : $db->query("UPDATE user SET num_weak_pwd_msg=0 WHERE ID=".$userId);
572 :
573 : /* Instanz der neuen Benutzersperre zurückgeben */
574 0 : return $ban;
575 : } else {
576 : /* Es könnte der Admin sein, oder ein exotischer Fehler
577 : * ist aufgetreten -> keine Sperre */
578 0 : return false;
579 : }
580 : } else {
581 0 : return false;
582 : }
583 : }
584 : }
|